package net.oschina.bilbodai.common.beanutil.property.mapping;

import net.oschina.bilbodai.common.beanutil.property.Property;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author daimao  Date: 2017/1/4 Time: 下午11:47
 * @version $Id$
 */
public class CollectMappingProperty implements MappingProperty<Map<String, Object>> {

    private final Property property;
    private final PropertyMapping propertyMapping;
    private final String baseKey;
    private final Property idxProperty;
    private final CollectionMappingMode collectMapMode;

    public CollectMappingProperty(Property property,
            PropertyMapping propertyMapping,
            String baseKey, Property idxProperty, CollectionMappingMode collectMapMode) {
        this.property = property;
        this.propertyMapping = propertyMapping;
        this.baseKey = baseKey;
        this.idxProperty = idxProperty;
        this.collectMapMode = collectMapMode;
    }

    @Override
    public Map<String, Object> getValue(Object target) {
        Collection collection = (Collection) property.get(target);
        Map<String, Object> ret = new HashMap<>();
        StringBuilder sb = new StringBuilder(baseKey);

        if (collectMapMode.ge(CollectionMappingMode.AS_ONE)) {
            ret.put(sb.toString(), collection);
        }

        if (collectMapMode.ge(CollectionMappingMode.RECURSIVE)) {

            sb.append(".");
            int len = sb.length();
            int idx = 0;
            for (Object item : collection) {
                Map<String, Object> inner = propertyMapping.from(item);
                if (inner != null && inner.size() > 0) {
                    for (Map.Entry<String, Object> e : inner.entrySet()) {
                        ret.put(sb.append(idxProperty == null ? idx : idxProperty.get(item)).append(".").append(e.getKey()).toString(), e.getValue());
                        sb.setLength(len);
                    }
                }
                idx++;
            }
        }

        return ret;
    }
}